package sjtu.pirate.analyzer;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import sjtu.pirate.format.FormResult;
import sjtu.pirate.format.FormResult.ResultType;
import sjtu.pirate.util.FormHelper;
/**
 * @author wilbur.ma@qq.com
 * @date 2011.06.01
 * Pirate Analyzer class.
 */
public class PirateAnalyzer implements Analyzer {
	/* results : <host, <name: list<FormResult>> */
	protected Hashtable<String, Hashtable<String, List<FormResult>>> results;
	
	public PirateAnalyzer() {
		this.results = new Hashtable<String, Hashtable<String, List<FormResult>>>();
	}
	
	/**
	 * Add FormResult to the current result collection.
	 */
	public void addResult(FormResult fr) {
		String host = fr.getForm().getURI().getHost();
		String path = FormHelper.buildFormPath(fr.getForm());
		boolean noHostP = false, noNameP = false;
		Hashtable<String, List<FormResult>> resultSameHost = results.get(host);
		if (resultSameHost == null) {
			resultSameHost = new Hashtable<String, List<FormResult>>();
			noHostP = true;
		}
		List<FormResult> resultSameName = resultSameHost.get(path);
		if (resultSameName == null) {
			resultSameName = new ArrayList<FormResult>();
			noNameP = true;
		}
		resultSameName.add(fr);
		if (noNameP)
			resultSameHost.put(path, resultSameName);
		if (noHostP)
			results.put(host, resultSameHost);
	}
	
	public Hashtable<String, Hashtable<String, List<FormResult>>> getResults() {
		return results;
	}
	
	public int getFailSitesNum() {
		int failSitesNum = 0;
		for (String host : results.keySet()) {
			int failForms = getFailFormsNum(host);
			if (failForms > 0)
				failSitesNum++;
		}
		return failSitesNum;
	}
	
	public int getAllFormsNum() {
		int formsNum = 0;
		for (String host : results.keySet()) {
			formsNum += results.get(host).size();
		}
		return formsNum;
	}
	
	public int getAllFailFormsNum() {
		int failFormsNum = 0;
		for (String host : results.keySet())
			failFormsNum += getFailFormsNum(host);
		return failFormsNum;
	}
	
	public int getFailFormsNum(String host) {
		int failNum = 0;
		Hashtable<String, List<FormResult>> table = results.get(host);
		for (String path : table.keySet()) {
			List<FormResult> list = table.get(path);
			for (FormResult fr : list) {
				if (fr.getResultType() != ResultType.OK) {
					failNum++;
					break;
				}
			}
		}
		return failNum;
	}
	
	public int getAllCasesNum() {
		int casesNum = 0;
		for (String host : results.keySet()) {
			Hashtable<String, List<FormResult>> table = results.get(host);
			for (String path : table.keySet()) {
				casesNum += table.get(path).size();
			}
		}
		return casesNum;
	}
	
	public int getAllFailCasesNum() {
		int failCasesNum = 0;
		for (String host : results.keySet())
			failCasesNum += getFailCasesNum(host);
		return failCasesNum;
	}
	
	public int getFailCasesNum(String host) {
		int failCasesNum = 0;
		Hashtable<String, List<FormResult>> table = results.get(host);
		if (table == null) {
			System.err.println(host + " not found.");
			return 0;
		}
		for (String path : table.keySet()) {
			List<FormResult> list = table.get(path);
			if (list != null)
				failCasesNum += getFailCasesNum(list);
		}
		return failCasesNum;
	}
	
	public int getFailCasesNum(List<FormResult> list) {
		int failNum = 0;
		for (FormResult fr : list) {
			if (fr.getResultType() != ResultType.OK)
				failNum++;
		}
		return failNum;
	}
	
	public boolean hasFailCases(String host) {
		Hashtable<String, List<FormResult>> table = results.get(host);
		for (String path : table.keySet()) {
			int failNum = getFailCasesNum(table.get(path));
			if (failNum != 0) {
				return true;
			}
		}
		return false;
	}
}
